#include "EntityKey_Control.h"

// 定义按键真实状态码
unsigned char Key_Code[Key_Sum + 1]={0};

void EntityKey_Init() {
    HAL_EntityKey_Init();
}

/**
 * @brief 按键扫描，请隔20ms扫描1次
 */
void EntityKey_Scan() {
    char i=0;
    static unsigned char KeyS[Key_Sum + 1]={0}; // 状态机
    static unsigned char CurrState[Key_Sum + 1]={0};
    static unsigned char PrevState[Key_Sum + 1]={0};
    static unsigned char Key_Count[Key_Sum + 1]={0}; // 各按键自己的计数值

    for (i = 1; i <= Key_Sum; i++) {             // 依次循环遍历4个按键
        PrevState[i] = CurrState[i];             // 保存上次状态
        CurrState[i] = HAL_EntityKey_ReadPin(i); // 保存本次状态

        switch (KeyS[i]) {
        case 0:                                           // S = 0：初始状态，等待按键按下
            if (PrevState[i] == 1 && CurrState[i] == 0) { // 刚才使抬起，现在是按下
                KeyS[i] = 1;
                Key_Count[i] = 0; // 计数器开始计时
            }
            break;
        case 1: // S=1 按键按下状态
            Key_Count[i]++;
            if (PrevState[i] == 0 && CurrState[i] == 1) { // 刚刚是按下，现在是抬起
                KeyS[i] = 2;
                Key_Count[i] = 0;
            } else if (Key_Count[i] >= 50) { // 按键按下超过50*20=1000ms，判定为长按
                KeyS[i] = 0;
                Key_Code[i] |= KEY_LONG; // 记录按键状态为长按
                #if KeyCalllback
                EntityKey_Trigger(i, KEY_LONG); // 触发事件回调函数
                #endif
            }
            break;
        case 2:
            Key_Count[i]++;
            if (PrevState[i] == 0 && CurrState[i] == 1) { // 200ms内再次按下并抬起，判定为双击
                KeyS[i] = 0;
                Key_Code[i] |= KEY_DOUBLE;
                #if KeyCalllback
                EntityKey_Trigger(i, KEY_DOUBLE); // 触发事件回调函数
                #endif
            } else if (Key_Count[i] >= 10) {
                KeyS[i] = 0;
                Key_Code[i] |= KEY_CLICK;
                #if KeyCalllback
                EntityKey_Trigger(i, KEY_CLICK); // 触发事件回调函数
                #endif
            }
            break;
        }
    }
}

/**
 * @brief 查看指定按键事件是否发生
 * @param index 按键编码从1开始
 * @param Event 按键事件名称
 */
char EntityKey_Check(unsigned char index, unsigned char Event) {
    if (index >= 1 && index <= Key_Sum) {
        if (Key_Code[index] & Event) {
            Key_Code[index] &= ~Event; // 清除事件
            return 1;
        }
    }
    return 0;
}

/**
 * @brief 所有按键事件清空
 */
void EntityKey_Clear() {
    char i;
    for (i = 1; i <= Key_Sum; i++) {
        Key_Code[i] = 0;
    }
}




